<?php
/**
 * Created by PhpStorm.
 * User: Inhere
 * Date: 2015/2/2
 * Time: 19:54
 * Use :
 * File: SessionLauncher.php
 */

namespace ulue\parts\session;


class SessionLauncher implements InterfaceSessionLauncher
{
    /**
     * session name
     * @var string
     */
//    protected $name;

    /**
     * session id
     * @var string
     */
//    protected $id;

    /**
     * session enabled
     * @var bool
     */
    protected $started=false;

    /**
     *
     * @var bool
     */
    protected $closed=true;

    public function __construct()
    {

        // Disable transparent sid support
        @ini_set('session.use_trans_sid', '0');

        // Only allow the session ID to come from cookies and nothing else.
        @ini_set('session.use_only_cookies', '1');
    }

    /**
     * 启动 session
     * @throws \DRuntimeException
     */
    public function start()
    {
        if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
            session_register_shutdown();
        } else {
            register_shutdown_function('session_write_close');
        }

        session_cache_limiter('none');

        if (!session_start()) {
            throw new \DRuntimeException('The session start-up failure');
        }

        $this->closed = false;

        return ($this->started = true);
    }

    public function isStarted()
    {
        return $this->started;
    }

    public function getId()
    {
        return session_id();
    }

    public function setId($id)
    {
        session_id($id);

        return $this;
    }

    public function getName()
    {
        return @session_name();
    }

    public function setName($name)
    {
        if ($this->isStarted())
        {
            throw new \DLogicException('不能改变已启动的session 会话名！');// Cannot change the name of an active session
        }

        @session_name($name);

        return $this;
    }

    public function restart($destroy = false, $lifetime = null)
    {
        if (null !== $lifetime)
        {
            ini_set('session.cookie_lifetime', $lifetime);
        }

        $return = $this->regenerate($destroy);

        // Workaround for https://bugs.php.net/bug.php?id=61470 as suggested by David Grudl
        @session_write_close();

        if (isset($_SESSION))
        {
            $backup = $_SESSION;
            $this->start();
            $_SESSION = $backup;
        }
        else
        {
            $this->start();
        }

        return $return;
    }

    // Update the current session id with a newly generated one
    public function regenerate($destroy = false)
    {
        return session_regenerate_id($destroy);
    }

    /**
     * Force the session to be saved and closed.
     *
     * This method must invoke session_write_close() unless this interface is
     * used for a storage object design for unit or functional testing where
     * a real PHP session would interfere with testing, in which case it
     * it should actually persist the session data if required.
     *
     * @return  void
     */
    public function save()
    {
        @session_write_close();

        $this->closed = true;
        $this->started = false;
    }

    /**
     * Clear all session data in memory.
     * @return  void
     */
    public function destroy()
    {
        // Need to destroy any existing sessions started with session.auto_start
        if (session_id())
        {
            @session_unset();
            @session_destroy();
        }

        $this->closed = true;
        $this->started = false;
    }

    /**
     * getCookieParams
     *
     * @return  array
     */
    public function getCookieParams()
    {
        return session_get_cookie_params();
    }

    /**
     * Set session cookie parameters, this method should call before session started.
     *
     * @param   integer  $lifetime  Lifetime of the session cookie, defined in seconds.
     * @param   string   $path      Path on the domain where the cookie will work. Use a single
     *                              slash ('/') for all paths on the domain.
     * @param   string   $domain    Cookie domain, for example 'www.php.net'. To make cookies
     *                              visible on all sub domains then the domain must be prefixed
     *                              with a dot like '.php.net'.
     * @param   boolean  $secure    If true cookie will only be sent over secure connections.
     * @param   boolean  $httpOnly  If set to true then PHP will attempt to send the httpOnly
     *                              flag when setting the session cookie.
     *
     * @return  static
     *
     */
    public function setCookieParams($lifetime, $path = null, $domain = null, $secure = false, $httpOnly = true)
    {
        session_set_cookie_params($lifetime, $path, $domain, $secure, $httpOnly);

        return $this;
    }

}// end class InitializeSession